﻿#include <windows.h>
#include <oleauto.h>
#include "simplecom.h"
// 全局变量
LONG g_cComponents = 0;  // 活跃组件计数
LONG g_cLocks = 0;       // 服务器锁计数
class CExampleComponent : public IExample
{
private:
    LONG m_cRef;                    // 引用计数
    wchar_t* m_Message;             // 存储的消息

public:
    // 构造函数
    CExampleComponent() : m_cRef(1), m_Message(nullptr)
    {
        // 设置默认消息
        const wchar_t* defaultMsg = L"Hello from COM Component!";
        size_t len = wcslen(defaultMsg) + 1;
        m_Message = new wchar_t[len];
        wcscpy_s(m_Message, len, defaultMsg);
        
        InterlockedIncrement(&g_cComponents); // 全局组件计数
    }

    // 析构函数
    ~CExampleComponent()
    {
        if (m_Message)
        {
            delete[] m_Message;
            m_Message = nullptr;
        }
        InterlockedDecrement(&g_cComponents); // 全局组件计数
    }

    // IUnknown 方法
    STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        if (ppv == nullptr) return E_POINTER;
        
        if (riid == IID_IUnknown || riid == IID_IExample)
        {
            *ppv = static_cast<IExample*>(this);
        }
        else
        {
            *ppv = nullptr;
            return E_NOINTERFACE;
        }
        
        AddRef();
        return S_OK;
    }

    STDMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&m_cRef);
    }

    STDMETHODIMP_(ULONG) Release()
    {
        ULONG refCount = InterlockedDecrement(&m_cRef);
        if (refCount == 0)
        {
            delete this;
        }
        return refCount;
    }

    // IExample 自定义方法
    STDMETHODIMP Add(int a, int b, int* result)
    {
        if (result == nullptr) return E_POINTER;
        
        *result = a + b;
        return S_OK;
    }

    STDMETHODIMP GetMessage(BSTR* message)
    {
        if (message == nullptr) return E_POINTER;
        
        *message = SysAllocString(m_Message);
        return (*message != nullptr) ? S_OK : E_OUTOFMEMORY;
    }

    STDMETHODIMP SetMessage(BSTR message)
    {
        if (message == nullptr) return E_INVALIDARG;
        
        // 释放旧消息
        if (m_Message)
        {
            delete[] m_Message;
        }
        
        // 分配新消息内存
        size_t len = SysStringLen(message) + 1;
        m_Message = new wchar_t[len];
        if (m_Message == nullptr) return E_OUTOFMEMORY;
        
        wcscpy_s(m_Message, len, message);
        return S_OK;
    }
};

// 类厂实现
class CExampleClassFactory : public IClassFactory
{
private:
    LONG m_cRef;

public:
    CExampleClassFactory() : m_cRef(1) 
    {
        InterlockedIncrement(&g_cLocks); // 全局锁计数
    }
    
    ~CExampleClassFactory()
    {
        InterlockedDecrement(&g_cLocks); // 全局锁计数
    }

    // IUnknown 方法
    STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        if (ppv == nullptr) return E_POINTER;
        
        if (riid == IID_IUnknown || riid == IID_IClassFactory)
        {
            *ppv = static_cast<IClassFactory*>(this);
        }
        else
        {
            *ppv = nullptr;
            return E_NOINTERFACE;
        }
        
        AddRef();
        return S_OK;
    }

    STDMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&m_cRef);
    }

    STDMETHODIMP_(ULONG) Release()
    {
        ULONG refCount = InterlockedDecrement(&m_cRef);
        if (refCount == 0)
        {
            delete this;
        }
        return refCount;
    }

    // IClassFactory 方法
    STDMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv)
    {
        if (ppv == nullptr) return E_POINTER;
        *ppv = nullptr;
        
        // 不支持聚合
        if (pUnkOuter != nullptr) return CLASS_E_NOAGGREGATION;
        
        // 创建组件实例
        CExampleComponent* pComponent = new CExampleComponent();
        if (pComponent == nullptr) return E_OUTOFMEMORY;
        
        // 查询请求的接口
        HRESULT hr = pComponent->QueryInterface(riid, ppv);
        pComponent->Release(); // 初始引用计数为1，这里释放
        
        return hr;
    }

    STDMETHODIMP LockServer(BOOL fLock)
    {
        if (fLock)
            InterlockedIncrement(&g_cLocks);
        else
            InterlockedDecrement(&g_cLocks);
        
        return S_OK;
    }
};



// DLL 导出函数
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
{
    if (ppv == nullptr) return E_POINTER;
    *ppv = nullptr;
    
    // 检查请求的CLSID是否匹配
    if (!IsEqualCLSID(rclsid, CLSID_ExampleComponent))
        return CLASS_E_CLASSNOTAVAILABLE;
    
    // 创建类厂
    CExampleClassFactory* pFactory = new CExampleClassFactory();
    if (pFactory == nullptr) return E_OUTOFMEMORY;
    
    // 查询请求的接口
    HRESULT hr = pFactory->QueryInterface(riid, ppv);
    pFactory->Release();
    
    return hr;
}

STDAPI DllCanUnloadNow()
{
    // 如果没有活跃组件且没有锁，则可以卸载
    if (g_cComponents == 0 && g_cLocks == 0)
        return S_OK;
    else
        return S_FALSE;
}

// DLL 入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}